home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue71 / Alfresco / TstRadix.dpr
Encoding:
Text File  |  2001-06-03  |  18.3 KB  |  690 lines

  1. {*********************************************************}
  2. {* TstRadix                                              *}
  3. {* Copyright (c) Julian M Bucknall 2001                  *}
  4. {* All rights reserved.                                  *}
  5. {*********************************************************}
  6. {* Algorithms Alfresco: Radix sorts                      *}
  7. {*********************************************************}
  8.  
  9. {Note: this unit is released as freeware. In other words, you are free
  10.        to use this unit in your own applications, however I retain all
  11.        copyright to the code. JMB}
  12.  
  13. program TstRadix;
  14.  
  15. {$APPTYPE CONSOLE}
  16.  
  17. uses
  18.   SysUtils,
  19.   Classes,
  20.   Windows;
  21.  
  22. const
  23.   ItemListCount = 100000;
  24.  
  25. type
  26.   DWordAsBytes = array [0..3] of byte;
  27.  
  28. {====================================================================}
  29. type
  30.   PaaItemByteKey = ^TaaItemByteKey;
  31.   TaaItemByteKey = record
  32.     ibkData : string;  // the data
  33.     ibkKey  : byte;    // the key
  34.   end;
  35.   PaaItemByteKeyList = ^TaaItemByteKeyList;
  36.   TaaItemByteKeyList = array [0..pred(ItemListCount)] of TaaItemByteKey;
  37.  
  38. procedure aaDistributionSort;
  39. var
  40.   i : integer;
  41.   ItemList : PaaItemByteKeyList;
  42.   AuxList  : PaaItemByteKeyList;
  43.   Counter : array [0..255] of integer;
  44.   PrevData : string;
  45.   PrevKey  : byte;
  46.   StartTime : dword;
  47.   EndTime   : dword;
  48. begin
  49.   writeln('Distribution sort on a byte key');
  50.  
  51.   {create an array of items with random keys to be sorted}
  52.   writeln('..building array to be sorted');
  53.   ItemList := Allocmem(sizeof(TaaItemByteKeyList));
  54.   for i := 0 to pred(ItemListCount) do begin
  55.     ItemList^[i].ibkData := Format('Item %5d', [i]);
  56.     ItemList^[i].ibkKey := random(256);
  57.   end;
  58.   writeln('..done, now starting sort...');
  59.   StartTime := GetTickCount;
  60.  
  61.   {clear the counter array}
  62.   FillChar(Counter, sizeof(Counter), 0);
  63.  
  64.   {calculate the distribution of each key}
  65.   for i := 0 to pred(ItemListCount) do
  66.     inc(Counter[ItemList^[i].ibkKey]);
  67.  
  68.   {calculate the cumulative distribution}
  69.   for i := 1 to 255 do
  70.     inc(Counter[i], Counter[i-1]);
  71.  
  72.   {create the auxiliary list}
  73.   New(AuxList);
  74.  
  75.   {copy over the items to the auxiliary list in sorted order}
  76.   for i := pred(ItemListCount) downto 0 do begin
  77.     dec(Counter[ItemList^[i].ibkKey]);
  78.     AuxList^[Counter[ItemList^[i].ibkKey]] := ItemList^[i];
  79.   end;
  80.   EndTime := GetTickCount;
  81.   writeln('..done (', EndTime - StartTime, ' millisecs)');
  82.   writeln('..checking sort order...');
  83.  
  84.   PrevData := '';
  85.   PrevKey := 0;
  86.   for i := 0 to pred(ItemListCount) do begin
  87.     if (AuxList^[i].ibkKey < PrevKey) then begin
  88.       writeln('Error: key out of sequence');
  89.       readln;
  90.     end
  91.     else if (AuxList^[i].ibkKey = PrevKey) then begin
  92.       if (AuxList^[i].ibkData <= PrevData) then begin
  93.         writeln('Error: sort not stable');
  94.         readln;
  95.       end;
  96.       PrevData := AuxList^[i].ibkData;
  97.     end
  98.     else begin
  99.       PrevKey := AuxList^[i].ibkKey;
  100.       PrevData := AuxList^[i].ibkData;
  101.     end;
  102.   end;
  103.   writeln('..done');
  104.  
  105. //  for i := 0 to pred(ItemListCount) do
  106. //    writeln(AuxList^[i].ibkKey:3, AuxList^[i].ibkData:12);
  107.  
  108.   Finalize(ItemList^);
  109.   FreeMem(ItemList);
  110.   Finalize(AuxList^);
  111.   FreeMem(AuxList);
  112. end;
  113. {====================================================================}
  114.  
  115.  
  116. {====================================================================}
  117. type
  118.   PaaItemStrKey = ^TaaItemStrKey;
  119.   TaaItemStrKey = record
  120.     ibkData : string;     // the data
  121.     ibkKey  : string[9];  // the key
  122.   end;
  123.   PaaItemStrKeyList = ^TaaItemStrKeyList;
  124.   TaaItemStrKeyList = array [0..pred(ItemListCount)] of TaaItemStrKey;
  125.  
  126. function GetRandomString : string;
  127. var
  128.   i : integer;
  129. begin
  130.   SetLength(Result, random(5) + 5);
  131.   for i := 1 to length(Result) do
  132.     Result[i] := char(random(26) + ord('a'));
  133. end;
  134.  
  135. procedure MSD(aFromList, aToList : PaaItemStrKeyList;
  136.               aFirst, aLast : integer;
  137.               aCharInx : integer);
  138. var
  139.   i : integer;
  140.   Inx : integer;
  141.   Counter : array [0..255] of integer;
  142.   Bins    : array [-1..255] of integer;
  143. begin
  144.   {exit if we reached the maximum character position}
  145.   if (aCharInx > 9) then
  146.     Exit;
  147.  
  148.   {if there's only one item, just exit: there's nothing to do}
  149.   if (aLast = aFirst) then
  150.     Exit;
  151.  
  152.   {clear the counter array}
  153.   FillChar(Counter, sizeof(Counter), 0);
  154.  
  155.   {calculate the distribution of each key}
  156.   for i := aFirst to aLast do
  157.     if (length(aFromList^[i].ibkKey) < aCharInx) then
  158.       inc(Counter[0])
  159.     else
  160.       inc(Counter[byte(aFromList^[i].ibkKey[aCharInx])]);
  161.  
  162.   {calculate the cumulative distribution}
  163.   Bins[-1] := 0;
  164.   Bins[0] := Counter[0];
  165.   for i := 1 to 255 do begin
  166.     inc(Counter[i], Counter[i-1]);
  167.     Bins[i] := Counter[i];
  168.   end;
  169.  
  170.   {copy over the items to the "to" list in sorted order}
  171.   for i := aLast downto aFirst do begin
  172.     if (length(aFromList^[i].ibkKey) < aCharInx) then begin
  173.       dec(Counter[0]);
  174.       aToList^[aFirst + Counter[0]] := aFromList^[i];
  175.     end
  176.     else begin
  177.       Inx := byte(aFromList^[i].ibkKey[aCharInx]);
  178.       dec(Counter[Inx]);
  179.       aToList^[aFirst + Counter[Inx]] := aFromList^[i];
  180.     end;
  181.   end;
  182.  
  183.   {move the sorted data back}
  184.   Move(aToList^[aFirst], aFromList^[aFirst],
  185.        succ(aLast - aFirst) * sizeof(TaaItemStrKey));
  186.  
  187.   {recursively sort each of the bins}
  188.   for i := 0 to 255 do begin
  189.     if (Bins[i] > Bins[i-1]) then
  190.       MSD(aFromList, aToList,
  191.           aFirst + Bins[i-1], aFirst + pred(Bins[i]),
  192.           succ(aCharInx));
  193.   end;
  194. end;
  195.  
  196. procedure aaMSDRadixSortStr;
  197. var
  198.   i : integer;
  199.   ItemList : PaaItemStrKeyList;
  200.   AuxList  : PaaItemStrKeyList;
  201.   PrevKey  : string;
  202.   StartTime : dword;
  203.   EndTime   : dword;
  204. begin
  205.   writeln('MSD radix sort on a string key');
  206.  
  207.   {create an array of items with random keys to be sorted}
  208.   writeln('..building array to be sorted');
  209.   ItemList := Allocmem(sizeof(TaaItemStrKeyList));
  210.   for i := 0 to pred(ItemListCount) do begin
  211.     ItemList^[i].ibkData := Format('Item %5d', [i]);
  212.     ItemList^[i].ibkKey := GetRandomString;
  213.   end;
  214.   writeln('..done, now starting sort...');
  215.  
  216.   {get time}
  217.   StartTime := GetTickCount;
  218.  
  219.   {allocate the auxiliary array}
  220.   New(AuxList);
  221.  
  222.   {sort the items}
  223.   MSD(ItemList, AuxList, 0, pred(ItemListCount), 1);
  224.  
  225.   {move them back}
  226.   EndTime := GetTickCount;
  227.   writeln('..done (', EndTime - StartTime, ' millisecs)');
  228.   writeln('..checking sort order...');
  229.  
  230.   PrevKey := '';
  231.   for i := 0 to pred(ItemListCount) do begin
  232.     if (ItemList^[i].ibkKey < PrevKey) then begin
  233.       writeln('Error: key out of sequence');
  234.       readln;
  235.     end
  236.     else begin
  237.       PrevKey := ItemList^[i].ibkKey;
  238.     end;
  239.   end;
  240.   writeln('..done');
  241.  
  242. //  for i := 0 to pred(ItemListCount) do
  243. //    writeln(ItemList^[i].ibkKey);
  244.  
  245.   Finalize(ItemList^);
  246.   FreeMem(ItemList);
  247.   Finalize(AuxList^);
  248.   FreeMem(AuxList);
  249. end;
  250.  
  251.  
  252. procedure aaLSDRadixSortStr;
  253. var
  254.   i : integer;
  255.   Inx      : integer;
  256.   CharInx  : integer;
  257.   ItemList : PaaItemStrKeyList;
  258.   AuxList  : PaaItemStrKeyList;
  259.   FromList : PaaItemStrKeyList;
  260.   ToList   : PaaItemStrKeyList;
  261.   Temp     : PaaItemStrKeyList;
  262.   Counter  : array [0..255] of integer;
  263.   PrevKey  : string;
  264.   StartTime : dword;
  265.   EndTime   : dword;
  266. begin
  267.   writeln('LSD radix sort on a string key');
  268.  
  269.   {create an array of items with random keys to be sorted}
  270.   writeln('..building array to be sorted');
  271.   ItemList := Allocmem(sizeof(TaaItemStrKeyList));
  272.   for i := 0 to pred(ItemListCount) do begin
  273.     ItemList^[i].ibkData := Format('Item %5d', [i]);
  274.     ItemList^[i].ibkKey := GetRandomString;
  275.   end;
  276.   writeln('..done, now starting sort...');
  277.  
  278.   {get time}
  279.   StartTime := GetTickCount;
  280.  
  281.   {allocate the auxiliary array}
  282.   New(AuxList);
  283.  
  284.   {prepare for the loop}
  285.   FromList := ItemList;
  286.   ToList := AuxList;
  287.  
  288.   {for each character in the key strings, from end to start...}
  289.   for CharInx := 9 downto 1 do begin
  290.  
  291.     {clear the counter array}
  292.     FillChar(Counter, sizeof(Counter), 0);
  293.  
  294.     {calculate the distribution of each key}
  295.     for i := 0 to pred(ItemListCount) do
  296.       if (length(FromList^[i].ibkKey) < CharInx) then
  297.         inc(Counter[0])
  298.       else
  299.         inc(Counter[byte(FromList^[i].ibkKey[CharInx])]);
  300.  
  301.     {calculate the cumulative distribution}
  302.     for i := 1 to 255 do
  303.       inc(Counter[i], Counter[i-1]);
  304.  
  305.     {copy over the items to the "to" list in sorted order}
  306.     for i := pred(ItemListCount) downto 0 do begin
  307.       if (length(FromList^[i].ibkKey) < CharInx) then begin
  308.         dec(Counter[0]);
  309.         ToList^[Counter[0]] := FromList^[i];
  310.       end
  311.       else begin
  312.         Inx := byte(FromList^[i].ibkKey[CharInx]);
  313.         dec(Counter[Inx]);
  314.         ToList^[Counter[Inx]] := FromList^[i];
  315.       end;
  316.     end;
  317.  
  318.     {switch over the to and from.lists}
  319.     Temp := FromList;
  320.     FromList := ToList;
  321.     ToList := Temp;
  322.   end;
  323.   if (FromList <> ItemList) then
  324.     Move(FromList^, ItemList^, sizeof(FromList^));
  325.   EndTime := GetTickCount;
  326.   writeln('..done (', EndTime - StartTime, ' millisecs)');
  327.   writeln('..checking sort order...');
  328.  
  329.   PrevKey := '';
  330.   for i := 0 to pred(ItemListCount) do begin
  331.     if (ItemList^[i].ibkKey < PrevKey) then begin
  332.       writeln('Error: key out of sequence');
  333.       readln;
  334.     end
  335.     else begin
  336.       PrevKey := FromList^[i].ibkKey;
  337.     end;
  338.   end;
  339.   writeln('..done');
  340.  
  341. //  for i := 0 to pred(ItemListCount) do
  342. //    writeln(ItemList^[i].ibkKey);
  343.  
  344.   Finalize(ItemList^);
  345.   FreeMem(ItemList);
  346.   Finalize(AuxList^);
  347.   FreeMem(AuxList);
  348. end;
  349. {====================================================================}
  350.  
  351.  
  352. {====================================================================}
  353. procedure QSS(aList    : PaaItemStrKeyList;
  354.               aFirst   : integer;
  355.               aLast    : integer);
  356. var
  357.   L, R  : integer;
  358.   Pivot : string[9];
  359.   Temp  : TaaItemStrKey;
  360. begin
  361.   {while there are at least two items to sort}
  362.   while (aFirst < aLast) do begin
  363.     {the pivot string is from the middle item}
  364.     Pivot := aList^[(aFirst+aLast) div 2].ibkKey;
  365.     {set indexes and partition}
  366.     L := pred(aFirst);
  367.     R := succ(aLast);
  368.     while true do begin
  369.       repeat dec(R); until (aList^[R].ibkKey <= Pivot);
  370.       repeat inc(L); until (aList^[L].ibkKey >= Pivot);
  371.       if (L >= R) then Break;
  372.       Temp := aList^[L];
  373.       aList^[L] := aList^[R];
  374.       aList^[R] := Temp;
  375.     end;
  376.     {quicksort the first subfile}
  377.     if (aFirst < R) then
  378.       QSS(aList, aFirst, R);
  379.     {quicksort the second subfile - recursion removal}
  380.     aFirst := succ(R);
  381.   end;
  382. end;
  383.  
  384. procedure aaStrQuickSort;
  385. var
  386.   i : integer;
  387.   ItemList : PaaItemStrKeyList;
  388.   PrevKey  : string;
  389.   StartTime : dword;
  390.   EndTime   : dword;
  391. begin
  392.   writeln('Quicksort on a string key');
  393.  
  394.   {create an array of items with random keys to be sorted}
  395.   writeln('..building array to be sorted');
  396.   ItemList := Allocmem(sizeof(TaaItemStrKeyList));
  397.   for i := 0 to pred(ItemListCount) do begin
  398.     ItemList^[i].ibkData := Format('Item %5d', [i]);
  399.     ItemList^[i].ibkKey := GetRandomString;
  400.   end;
  401.   writeln('..done, now starting sort...');
  402.  
  403.   {get time}
  404.   StartTime := GetTickCount;
  405.  
  406.   {sort}
  407.   QSS(ItemList, 0, pred(ItemListCount));
  408.  
  409.   {finish}
  410.   EndTime := GetTickCount;
  411.   writeln;
  412.   writeln('..done (', EndTime - StartTime, ' millisecs)');
  413.   writeln('..checking sort order...');
  414.  
  415.   PrevKey := '';
  416.   for i := 0 to pred(ItemListCount) do begin
  417.     if (ItemList^[i].ibkKey < PrevKey) then begin
  418.       writeln('Error: key out of sequence');
  419.       readln;
  420.     end
  421.     else begin
  422.       PrevKey := ItemList^[i].ibkKey;
  423.     end;
  424.   end;
  425.   writeln('..done');
  426.  
  427. //  for i := 0 to pred(ItemListCount) do
  428. //    writeln(ItemList^[i].ibkKey);
  429.  
  430.   Finalize(ItemList^);
  431.   FreeMem(ItemList);
  432. end;
  433. {====================================================================}
  434.  
  435.  
  436. {====================================================================}
  437. type
  438.   PaaItemU32Key = ^TaaItemU32Key;
  439.   TaaItemU32Key = record
  440.     ibkData : string;    // the data
  441.     ibkKey  : longword;  // the key
  442.   end;
  443.   PaaItemU32KeyList = ^TaaItemU32KeyList;
  444.   TaaItemU32KeyList = array [0..pred(ItemListCount)] of TaaItemU32Key;
  445.  
  446. function GetRandomU32 : longword;
  447. var
  448.   i : integer;
  449. begin
  450.   for i := 0 to 3 do
  451.     DWordAsBytes(Result)[i] := random(256);
  452. end;
  453.  
  454. procedure aaLSDRadixSortU32;
  455. var
  456.   i : integer;
  457.   Inx      : integer;
  458.   CharInx  : integer;
  459.   ItemList : PaaItemU32KeyList;
  460.   AuxList  : PaaItemU32KeyList;
  461.   FromList : PaaItemU32KeyList;
  462.   ToList   : PaaItemU32KeyList;
  463.   Temp     : PaaItemU32KeyList;
  464.   Counter  : array [0..255] of integer;
  465.   PrevKey  : longword;
  466.   StartTime : dword;
  467.   EndTime   : dword;
  468. begin
  469.   writeln('LSD radix sort on an unsigned 32-bit key');
  470.  
  471.   {create an array of items with random keys to be sorted}
  472.   writeln('..building array to be sorted');
  473.   ItemList := Allocmem(sizeof(TaaItemStrKeyList));
  474.   for i := 0 to pred(ItemListCount) do begin
  475.     ItemList^[i].ibkData := Format('Item %5d', [i]);
  476.     ItemList^[i].ibkKey := GetRandomU32;
  477.   end;
  478.   writeln('..done, now starting sort...');
  479.  
  480.   {get time}
  481.   StartTime := GetTickCount;
  482.  
  483.   {allocate the auxiliary array}
  484.   New(AuxList);
  485.  
  486.   {prepare for the loop}
  487.   FromList := ItemList;
  488.   ToList := AuxList;
  489.  
  490.   {for each digit in the key longwords, from start to end...}
  491.   for CharInx := 0 to 3 do begin
  492.  
  493.     {clear the counter array}
  494.     FillChar(Counter, sizeof(Counter), 0);
  495.  
  496.     {calculate the distribution of each key}
  497.     for i := 0 to pred(ItemListCount) do
  498.       inc(Counter[DWordAsBytes(FromList^[i].ibkKey)[CharInx]]);
  499.  
  500.     {calculate the cumulative distribution}
  501.     for i := 1 to 255 do
  502.       inc(Counter[i], Counter[i-1]);
  503.  
  504.     {copy over the items to the "to" list in sorted order}
  505.     for i := pred(ItemListCount) downto 0 do begin
  506.       Inx := DWordAsBytes(FromList^[i].ibkKey)[CharInx];
  507.       dec(Counter[Inx]);
  508.       ToList^[Counter[Inx]] := FromList^[i];
  509.     end;
  510.  
  511.     {switch over the to and from.lists}
  512.     Temp := FromList;
  513.     FromList := ToList;
  514.     ToList := Temp;
  515.   end;
  516.   EndTime := GetTickCount;
  517.   writeln;
  518.   writeln('..done (', EndTime - StartTime, ' millisecs)');
  519.   writeln('..checking sort order...');
  520.  
  521.   PrevKey := 0;
  522.   for i := 0 to pred(ItemListCount) do begin
  523.     if (ItemList^[i].ibkKey < PrevKey) then begin
  524.       writeln('Error: key out of sequence');
  525.       readln;
  526.     end
  527.     else begin
  528.       PrevKey := FromList^[i].ibkKey;
  529.     end;
  530.   end;
  531.   writeln('..done');
  532.  
  533. //  for i := 0 to pred(ItemListCount) do
  534. //    writeln(ItemList^[i].ibkKey);
  535.  
  536.   Finalize(ItemList^);
  537.   FreeMem(ItemList);
  538.   Finalize(AuxList^);
  539.   FreeMem(AuxList);
  540. end;
  541. {====================================================================}
  542.  
  543.  
  544. {====================================================================}
  545. type
  546.   PaaItemS32Key = ^TaaItemS32Key;
  547.   TaaItemS32Key = record
  548.     ibkData : string;    // the data
  549.     ibkKey  : longint;   // the key
  550.   end;
  551.   PaaItemS32KeyList = ^TaaItemS32KeyList;
  552.   TaaItemS32KeyList = array [0..pred(ItemListCount)] of TaaItemS32Key;
  553.  
  554. function GetRandomS32 : longword;
  555. var
  556.   i : integer;
  557. begin
  558.   for i := 0 to 3 do
  559.     DWordAsBytes(Result)[i] := random(256);
  560. end;
  561.  
  562. procedure aaLSDRadixSortS32;
  563. var
  564.   i : integer;
  565.   Inx      : integer;
  566.   CharInx  : integer;
  567.   ItemList : PaaItemS32KeyList;
  568.   AuxList  : PaaItemS32KeyList;
  569.   FromList : PaaItemS32KeyList;
  570.   ToList   : PaaItemS32KeyList;
  571.   Temp     : PaaItemS32KeyList;
  572.   Counter  : array [0..255] of integer;
  573.   PrevKey  : longint;
  574.   StartTime : dword;
  575.   EndTime   : dword;
  576. begin
  577.   writeln('LSD radix sort on a signed 32-bit key');
  578.  
  579.   {create an array of items with random keys to be sorted}
  580.   writeln('..building array to be sorted');
  581.   ItemList := Allocmem(sizeof(TaaItemStrKeyList));
  582.   for i := 0 to pred(ItemListCount) do begin
  583.     ItemList^[i].ibkData := Format('Item %5d', [i]);
  584.     ItemList^[i].ibkKey := GetRandomS32;
  585.   end;
  586.   writeln('..done, now starting sort...');
  587.  
  588.   {get time}
  589.   StartTime := GetTickCount;
  590.  
  591.   {allocate the auxiliary array}
  592.   New(AuxList);
  593.  
  594.   {prepare for the loop}
  595.   FromList := ItemList;
  596.   ToList := AuxList;
  597.  
  598.   {for each digit in the key longwords, from start to end...}
  599.   for CharInx := 0 to 3 do begin
  600.  
  601.     {clear the counter array}
  602.     FillChar(Counter, sizeof(Counter), 0);
  603.  
  604.     {calculate the distribution of each key}
  605.     if (CharInx = 3) then
  606.       for i := 0 to pred(ItemListCount) do begin
  607.         Inx := (DWordAsBytes(FromList^[i].ibkKey)[CharInx]) xor $80;
  608.         inc(Counter[Inx]);
  609.       end
  610.     else
  611.       for i := 0 to pred(ItemListCount) do begin
  612.         Inx := DWordAsBytes(FromList^[i].ibkKey)[CharInx];
  613.         inc(Counter[Inx]);
  614.       end;
  615.  
  616.     {calculate the cumulative distribution}
  617.     for i := 1 to 255 do
  618.       inc(Counter[i], Counter[i-1]);
  619.  
  620.     {copy over the items to the "to" list in sorted order}
  621.     if (CharInx = 3) then
  622.       for i := pred(ItemListCount) downto 0 do begin
  623.         Inx := (DWordAsBytes(FromList^[i].ibkKey)[CharInx]) xor $80;
  624.         dec(Counter[Inx]);
  625.         ToList^[Counter[Inx]] := FromList^[i];
  626.       end
  627.     else
  628.       for i := pred(ItemListCount) downto 0 do begin
  629.         Inx := DWordAsBytes(FromList^[i].ibkKey)[CharInx];
  630.         dec(Counter[Inx]);
  631.         ToList^[Counter[Inx]] := FromList^[i];
  632.       end;
  633.  
  634.     {switch over the to and from.lists}
  635.     Temp := FromList;
  636.     FromList := ToList;
  637.     ToList := Temp;
  638.   end;
  639.   EndTime := GetTickCount;
  640.   writeln;
  641.   writeln('..done (', EndTime - StartTime, ' millisecs)');
  642.   writeln('..checking sort order...');
  643.  
  644.   PrevKey := -MaxLongInt;
  645.   for i := 0 to pred(ItemListCount) do begin
  646.     if (ItemList^[i].ibkKey < PrevKey) then begin
  647.       writeln('Error: key out of sequence');
  648.       readln;
  649.     end
  650.     else begin
  651.       PrevKey := FromList^[i].ibkKey;
  652.     end;
  653.   end;
  654.   writeln('..done');
  655.  
  656. //  for i := 0 to pred(ItemListCount) do
  657. //    writeln(ItemList^[i].ibkKey);
  658.  
  659.   Finalize(ItemList^);
  660.   FreeMem(ItemList);
  661.   Finalize(AuxList^);
  662.   FreeMem(AuxList);
  663. end;
  664. {====================================================================}
  665.  
  666.  
  667.  
  668. begin
  669.   try
  670.     writeln('Radix sort testing');
  671.  
  672.     aaDistributionSort;
  673.  
  674.     aaMSDRadixSortStr;
  675.  
  676.     aaLSDRadixSortStr;
  677.     aaStrQuicksort;
  678.  
  679.     aaLSDRadixSortU32;
  680.     aaLSDRadixSortS32;
  681.  
  682.     writeln('Tests completed');
  683.   except
  684.     on E : Exception do
  685.       writeln(E.Message);
  686.   end;
  687.   readln;
  688. end.
  689.  
  690.